package users

import (
	"../common"
	"../web"
	"fmt"
	"net/http"
	"strings"
)

type ChangePwdObj struct {
	common.BaseHandler
}

func IndexHandler(ctx *web.Context) {
	_, flg := common.GetUser(ctx)
	if !flg {
		return
	}

	common.RenderTemplate(ctx, &map[string]interface{}{}, "index.html")
}

func LoginHandler(ctx *web.Context) {
	usr := common.CurrentUser(ctx)
	if usr != nil {
		IndexHandler(ctx)
		return
	}

	types := *common.FetchAllRowsPtr(
		`SELECT RTRIM(PRODTYPE), RTRIM(ISNULL(TYPECHN,'')), ''
           FROM SFC_PRODUCT(NOLOCK) 
          ORDER BY BARCODE`,
		common.ConnectString, new(common.ProdType))

	tmplData := make(map[string]interface{})
	tmplData["types"] = types

	lang := common.DefaultLanguage
	if ctx.Request.Method == "POST" {
		usr := ctx.Params["username"]
		pwd := ctx.Params["password"]
		prd := strings.TrimSpace(ctx.Params["prodid"])
		if prd == "" {
			tmplData["error"] = common.GetText(lang, "Please select the Product.")
			common.RenderSingleTemplate(ctx, &tmplData, "login.html")
			return
		}
		password := common.EncryptPassword(pwd)
		sRtnData := *common.FetchOneRowPtr(
			`SELECT TOP 1 NAME 
			   FROM SFC_EMPLOYEE(NOLOCK) 
			  WHERE ID=? 
			    AND PWD=? 
			    AND EXPIRED=0`,
			common.ConnectString, new(common.RecDataStr), usr, password)
		realname := sRtnData.(common.RecDataStr).Data
		if realname != "" {
			localusr := new(common.User)
			localusr.Username = usr
			localusr.Realname = realname
			localusr.Password = password
			localusr.Photo = ""
			localusr.Expired = 0
			localusr.Language = lang
			sess := common.NewSession()
			ctx.SetSecureCookie("sfcsession", string(sess), 0)
			sRtnData := *common.FetchAllRowsPtr(
				`SELECT B.RIGHTSID, B.RIGHTSURL 
				   FROM SFC_RIGHTS B(NOLOCK)
				   JOIN SFC_USERRIGHTS A(NOLOCK)
					 ON A.RIGHTSID=B.RIGHTSID
					AND A.USERID=?
				  ORDER BY B.RIGHTSID`,
				common.ConnectString, new(common.RightsInfo), usr)
			i18nDict := common.Url_Chn
			if lang == "en_US" {
				i18nDict = common.Url_Eng
			}
			for _, val := range sRtnData {
				rightid := val.(common.RightsInfo).RightsId
				righturl := strings.TrimSpace(val.(common.RightsInfo).RightsUrl)
				dict := map[string]string{righturl: i18nDict[righturl]}
				switch {
				case rightid < 200:
					localusr.RUser = append(localusr.RUser, dict)
				case rightid < 300:
					localusr.RSets = append(localusr.RSets, dict)
				case rightid < 400:
					localusr.ROper = append(localusr.ROper, dict)
				case rightid < 500:
					localusr.RQuery = append(localusr.RQuery, dict)
				default:
					localusr.RWono = append(localusr.RWono, dict)
				}
			}
			localusr.Conn = "driver={" + common.Config["driver"] + "};server=" +
				common.Config["server"] + ";database=" + common.Config[prd] + ";uid=" +
				common.Config["uid"] + ";pwd=" + common.Config["pwd"]
			localusr.Prod = common.Config[prd+"_type"]
			localusr.DBName = common.Config[prd]
			sess.Put("user", localusr)
			sess.Put("flash", "")
			sess.UpdateSession()
			ctx.Redirect(http.StatusFound, "/index")
			return
		} else {
			tmplData["error"] = common.GetText(lang, "Invalid Username or Password.")
			common.RenderSingleTemplate(ctx, &tmplData, "login.html")
			return
		}
	}

	common.RenderSingleTemplate(ctx, &tmplData, "login.html")
}

func LogoutHandler(ctx *web.Context) {
	usr := common.CurrentUser(ctx)
	if usr != nil {
		ss, _ := ctx.GetSecureCookie("sfcsession")
		sess := common.SessionFromId(ss)
		sess.RemoveSession()
	}

	ctx.Redirect(http.StatusFound, "/login")
}

func (self *ChangePwdObj) Prepare() {}

func (self *ChangePwdObj) ParameterCheck() bool {
	oldp := self.Ctx.Params["oldpassword"]
	newp := self.Ctx.Params["newpassword"]
	newp2 := self.Ctx.Params["newpassword2"]
	if common.EncryptPassword(oldp) != self.Usr.Password {
		self.TmplData["error"] = common.GetText(self.Lang, "Old Password is invalid.")
		return false
	}
	if newp != newp2 {
		self.TmplData["error"] = common.GetText(self.Lang, "New Password not match.")
		return false
	}
	if newp == "" {
		self.TmplData["error"] = common.GetText(self.Lang, "New Password must be not empty.")
		return false
	}

	self.Sqlparas = append(self.Sqlparas, common.EncryptPassword(newp))
	self.Sqlparas = append(self.Sqlparas, self.Usr.Username)
	self.Flashparas = []interface{}{self.Usr.Realname}

	return true
}

func (self *ChangePwdObj) SqlExecute() bool {
	err := common.ExecSqlNonRst(`UPDATE SFC_EMPLOYEE WITH(ROWLOCK) SET PWD=? WHERE ID=?`,
		common.ConnectString, self.Sqlparas...)
	if err != nil {
		common.Application.SendMail(fmt.Sprintf("Update User [%s] Password Error: %v\n", self.Usr.Username, err))
		return false
	}
	self.Usr.Password = self.Sqlparas[0].(string)

	return true
}

func ChangePwdHandler(ctx *web.Context) {
	self := new(ChangePwdObj)
	self.Ctx = ctx
	self.Url = "/changepwd"
	self.Html = "changepwd.html"
	self.Flashstr = "User %v have been changed password."
	self.Do(self)
}

func LanguageHandler(ctx *web.Context) {
	_, flg := ctx.GetSecureCookie("sfcsession")
	if flg {
		usr := common.CurrentUser(ctx)
		if usr == nil {
			ctx.Redirect(http.StatusFound, "/login")
			return
		}

		curr_menu := common.Url_Chn

		if usr.Language == "zh_CN" {
			usr.Language = "en_US"
			curr_menu = common.Url_Eng
		} else {
			usr.Language = "zh_CN"
		}

		// change MENU
		for _, url := range usr.ROper {
			for k, _ := range url {
				url[k] = curr_menu[k]
			}
		}
		for _, url := range usr.RQuery {
			for k, _ := range url {
				url[k] = curr_menu[k]
			}
		}
		for _, url := range usr.RWono {
			for k, _ := range url {
				url[k] = curr_menu[k]
			}
		}
		for _, url := range usr.RSets {
			for k, _ := range url {
				url[k] = curr_menu[k]
			}
		}
		for _, url := range usr.RUser {
			for k, _ := range url {
				url[k] = curr_menu[k]
			}
		}
	}

	ctx.Redirect(http.StatusFound, "/index")
}
